package cn.tedu.charging.order.service.impl;

import cn.tedu.charging.common.pojo.jsonResult.JsonResult;
import cn.tedu.charging.common.pojo.jsonResult.param.GunStatusUpdateParam;
import cn.tedu.charging.common.pojo.jsonResult.util.JsonUtils;
import cn.tedu.charging.common.pojo.jsonResult.vo.StationInfoVO;
import cn.tedu.charging.common.pojo.jsonResult.vo.UserInfoVO;
import cn.tedu.charging.order.common.ChargingConstants;
import cn.tedu.charging.order.common.GunStatusConstants;
import cn.tedu.charging.order.common.MqttConstants;
import cn.tedu.charging.order.feign.DeviceClient;
import cn.tedu.charging.order.feign.UserClient;
import cn.tedu.charging.order.mqtt.MqttProducer;
import cn.tedu.charging.order.pojo.param.OrderAddParam;
import cn.tedu.charging.order.pojo.dto.ChargingDto;
import cn.tedu.charging.order.quartz.DeviceCheckJob;
import cn.tedu.charging.order.rabbitmq.RabbitMQProducer;
import cn.tedu.charging.order.service.OrderService;
import lombok.extern.slf4j.Slf4j;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.Random;


@Slf4j
@Service
public class OrderServiceImpl implements OrderService {


    @Override
    public String createOrder(OrderAddParam orderAddParam) {
        log.debug("创建订单-orderService:入参:{}",orderAddParam);
        //1. 生成订单号
        log.debug("创建订单-orderService:开始生成订单号");
        String orderNo = getOrderNo();
        log.debug("创建订单-orderService:生成订单号:{}",orderNo);
        //2. 获取用户信息
        Integer userId = orderAddParam.getUserId();//先从前端拿到用户id，通过用户id拿到用户信息
        log.debug("创建订单-orderService:开始获取用户信息:入参:{}",userId);
        UserInfoVO userInfo = getUserInfoByOpenFeign(userId);
        log.debug("创建订单-orderService:获取用户信息:入参:{},出参:{}",userId,userInfo);
        //3.更新枪的状态
       log.debug("创建订单-orderService:开始更新枪的状态:入参:枪id:{},枪状态:{}",orderAddParam.getGunId(),GunStatusConstants.GUN_STATUS_USING);
        Boolean success = updateGunStatus(orderAddParam.getGunId(), GunStatusConstants.GUN_STATUS_USING);
       log.debug("创建订单-orderService:更新枪的状态:入参:枪id:{},枪状态:{},出参:{}",orderAddParam.getGunId(),GunStatusConstants.GUN_STATUS_USING,success);


        //4.获取场地信息
        log.debug("创建订单-orderService:获取场站信息:入参:{}", orderAddParam.getGunId());
        StationInfoVO stationInfo =getStationInfo(orderAddParam.getGunId());
        log.debug("创建订单-orderService:获取场站信息:入参:{},出参:{}", orderAddParam.getGunId(),stationInfo);

        //5.订单服务向设备服务发送开始充电指令
        startCharging(orderNo,orderAddParam.getPileId(),orderAddParam.getGunId());
        log.debug("创建订单-orderService:入参:{},出参:{}",orderAddParam,orderNo);

        //6.
        log.debug("创建订单-orderService:创建设备检查任务:");
        try {
            DeviceCheckJob deviceCheckJob = new DeviceCheckJob(orderNo);
        } catch (SchedulerException e) {
            log.error("创建订单-orderService:创建设备检查任务:异常:{}", e);
        }
        //7 发送消息到RabbitMQ通过死信队列实现延迟消息处理超时订单
        log.debug("创建订单-orderService:发送消息到RabbitMQ通过死信队列实现延迟消息处理超时订单:入参:{}", orderNo);
        Boolean result = sendMessage(orderNo);
        log.debug("创建订单-orderService:发送消息到RabbitMQ通过死信队列实现延迟消息处理超时订单:入参:{},出参:{}", orderNo,result);

        log.debug("创建订单-orderService:创建设备检查任务成功:");
        return orderNo;


    }
    @Autowired
    private RabbitMQProducer rabbitMQProducer;


    /**
     * 发送消息到RabbitMQ通过死信队列实现延迟消息处理超时订单
     * @return
     */
    private Boolean sendMessage(String orderNo){
        rabbitMQProducer.send(orderNo);
        return true;
    }

    @Autowired
    private MqttProducer mqttProducer;
    /**
     * 订单服务向设备服务发送开始充电指令
     * @return
     *
     */
    private void startCharging(String orderNo,Integer pileId,  Integer gunId) {
        String topic = MqttConstants.TOPIC_START_CHARGING_PREFIX+pileId;
        ChargingDto ChargingDto = new ChargingDto();
        ChargingDto.setOrderNo(orderNo);
        ChargingDto.setPileId(pileId);
        ChargingDto.setGunId(gunId);
        ChargingDto.setMsg(ChargingConstants.START_CHARGING);
        String message = JsonUtils.toJson(ChargingDto);
        log.debug("发送开始充电指令:topic:{},消息:{}", topic,message);
        Boolean success = mqttProducer.send(topic, message);
        log.debug("发送开始充电指令:topic:{},消息:{},发送结果:{}", topic,message,success);
    }

    /**
     * 生成订单号
     * @return
     */
    private String getOrderNo(){
        return "666";
    }
    @Autowired
    private DeviceClient deviceClient;
    /**
     * 更新枪的状态
     * @param gunId
     * @param status
     * @return
     */
    private Boolean updateGunStatus(Integer gunId, Integer status) {
        GunStatusUpdateParam param = new GunStatusUpdateParam();
        param.setGunId(gunId);
        param.setStatus(status);
        JsonResult<Boolean> result = deviceClient.updateGunStatus(param);
        if (result != null) {
            return result.getData();
        }
        return false;

    }

    private StationInfoVO getStationInfo(Integer gunId) {
        JsonResult<StationInfoVO> result = deviceClient.getStationInfo(gunId);
        if (result != null) {
            return result.getData();
        }
        return null;
    }

    /**
     * 通过用户id，获取用户信息
     */
    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private UserClient userClient;
    private UserInfoVO getUserInfoByOpenFeign(Integer userId) {
        JsonResult<UserInfoVO> userInfo = userClient.getUserInfo(userId);
        UserInfoVO data = userInfo.getData();
        return data;
    }

        //使用了openFeign,所以以下代码不需要了

//    private UserInfoVO getUserInfo(Integer userId) {
//        String url = getRandomUrl();
//        log.debug("随机获取的用户服务的URL:{}",url);
//        ParameterizedTypeReference<JsonResult<UserInfoVO>> repType = new ParameterizedTypeReference<JsonResult<UserInfoVO>>() {};
//        ResponseEntity<JsonResult<UserInfoVO>> entity = restTemplate.exchange(url, HttpMethod.GET, null, repType, userId);
//        JsonResult<UserInfoVO> body = entity.getBody();
//        UserInfoVO data = body.getData();
//        return data;
//    }

    /**
     * 随机获取用户服务的URL
     *
     */
    private String getRandomUrl(){
        String url0="http://localhost:8080/user/info/{userId}";
        String url1="http://localhost:8081/user/info/{userId}";
        String url2="http://localhost:8082/user/info/{userId}";
        String[] urls= new String[]{url0, url1, url2};
        Random random = new Random();
        int index = random.nextInt(urls.length);
        return urls[index];
    }
}
